import {
    CommentOutlined, CopyOutlined, DeleteOutlined, DislikeOutlined, EllipsisOutlined, FireOutlined
    , HeartOutlined, LikeOutlined, PlusCircleOutlined, PlusOutlined, ReadOutlined,
    ShareAltOutlined, SmileOutlined, SyncOutlined, UserOutlined
} from '@ant-design/icons';
import { Bubble, Conversations, ConversationsProps, Prompts, Sender, Suggestion, useXAgent, useXChat, Welcome, XRequest } from '@ant-design/x';
import { Button, Flex, Form, GetRef, Input, message, Modal, Space, Spin, type GetProp } from 'antd';
import React, { ReactElement, useEffect, useRef, useState } from 'react';
import MarkdownRender from '../../components/MarkdownRender';
import encrypt, { debounceTime, formatTimestamp, fromTime } from '../../utils/utils';
import { v4 as uuidv4 } from 'uuid';
import _ from 'lodash';
import { useLocalStorageState } from 'ahooks';
import globalData from '../../store/global';
import useVariable from '@/store/useVariable';

const layout = {
    labelCol: { span: 4 },
    wrapperCol: { span: 18 },
};

interface ConversationsItems {
    key: string;
    label: string | ReactElement;
    group?: string;
    timestamp: number;
    data: any[];
}

const debounce = debounceTime(500);

const renderTitle = (icon: ReactElement, title: string) => (
    <Space align="start">
        {icon}
        <span>{title}</span>
    </Space>
);

const currentTimestamp = fromTime();

const defaultConversationsItems = [
    {
        key: '0',
        label: '新聊天',
        data: [],
        group: currentTimestamp + "",
        timestamp: currentTimestamp,
    },
];

const placeholderPromptsItems: GetProp<typeof Prompts, 'items'> = [
    {
        key: '1',
        label: renderTitle(<FireOutlined style={{ color: '#FF4D4F' }} />, '热门话题'),
        description: '创建可视化大屏?',
        children: [
            {
                key: '1-1',
                description: `如何创建可视化大屏?`,
            },
            {
                key: '1-2',
                description: `如何创建团队？`,
            },
            {
                key: '1-3',
                description: `如何添加团队成员？`,
            },
        ],
    },
    {
        key: '2',
        label: renderTitle(<ReadOutlined style={{ color: '#1890FF' }} />, '设计指南'),
        description: '什么是X-DigitalView?',
        children: [
            {
                key: '2-1',
                icon: <HeartOutlined />,
                description: `支持哪些数据源？`,
            },
            {
                key: '2-2',
                icon: <SmileOutlined />,
                description: `组件如何绑定变量？`,
            },
            {
                key: '2-3',
                icon: <CommentOutlined />,
                description: `如何部署制作好的大屏？`,
            },
        ],
    },
];

type SuggestionItems = Exclude<GetProp<typeof Suggestion, 'items'>, () => void>;
const suggestions: SuggestionItems = [
    { label: '你是谁？', value: '你是谁？' },
    { label: '你能为我做什么？', value: '你能为我做什么？' },
];

interface Props {
    sidebar?: boolean
    onRun?: (run: boolean) => void
}

const ChatWhite = (props: Props) => {
    const { sidebar = true, onRun } = props;
    const [content, setContent] = useState('');
    const createRef = useRef<any>();
    const [title, setTitle] = useState('')
    const [activeKey, setActiveKey] = useLocalStorageState(
        "conversations-key", {
        defaultValue: defaultConversationsItems[0].key,
    });
    const stopRef = useRef(false)
    const [isParams, setIsParams] = useState(false)
    const [form] = Form.useForm();

    const roles: GetProp<typeof Bubble.List, 'roles'> = {
        ai: {
            placement: 'start',
            avatar: sidebar && <img src="img/ai.webp" className='h-[42px]' />,
            loadingRender: () => {
                return <Space>
                    <Spin size="small" />
                </Space>
            },
            messageRender: (content) => {
                return <div>{content}</div>
            },
        },
        local: {
            placement: 'end',
            avatar: sidebar && { icon: <UserOutlined />, style: { background: '#87d068' } },
        },
    };

    const [conversationsItems, setConversationsItems] = useLocalStorageState<ConversationsItems[]>(
        'use-local-storage-state-conversations-items',
        {
            defaultValue: defaultConversationsItems,
        },
    );

    const listRef = React.useRef<GetRef<typeof Bubble.List>>(null);

    const menuConfig: ConversationsProps['menu'] = (conversation) => ({
        items: [
            {
                label: '删除',
                key: 'delete',
                icon: <DeleteOutlined />,
                danger: true,
            },
        ],
        onClick: (menuInfo) => {
            setConversationsItems((items) => items.filter((item) => item.key !== conversation.key));
        },
    });

    useEffect(() => {
        const searchParams = new URLSearchParams(window.location.search);
        const projectId = encrypt(searchParams.get('projectId'));
        const { create } = XRequest({
            baseURL: import.meta.env.VITE_LLM_API_API + '/v1/chat/completions',
            dangerouslyApiKey: "Bearer " + projectId,
            model: 'gpt-4o-mini',
        });
        createRef.current = create;
        setTitle(searchParams.get('projectName'));

        if (sidebar) {
            const data = conversationsItems?.find((item) => item.key === activeKey)?.data
            if (data) {
                setMessages(data);
            }
        } else {
            setMessages([])
        }
    }, [])

    const [agent] = useXAgent({
        request: async ({ message, messages }, { onSuccess, onUpdate }) => {
            let currentContent = '';

            // 转标准格式会话
            const formattedMessages = messages.map((msg, index) => ({
                role: index % 2 === 0 ? "user" : "assistant",
                content: msg
            }));
            onUpdate("...")
            onRun && onRun(true)
            
            try {
                createRef.current(
                    {
                        messages: [
                            { role: "system", content: "" }, ...formattedMessages],
                        stream: true,
                        variable: {
                            userId: globalData.userId,
                            ... form.getFieldsValue()
                        }
                    },
                    {
                        onSuccess: (chunks) => {
                            onSuccess(currentContent);
                            onRun && onRun(false)
                        },
                        onError: (error) => {
                            console.log('error', error);
                        },
                        onUpdate: (chunk) => {
                            try {
                                const data = JSON.parse(chunk.data);
                                currentContent += data?.choices[0].delta.content ? data?.choices[0].delta.content : "";
                                if (stopRef.current) {
                                    onSuccess(currentContent)
                                    stopRef.current = false
                                }
                                onUpdate(currentContent);
                            } catch (e) {
                            }
                        },
                    },
                );
            } catch (error) {
                onSuccess(error.message);
            }
        },
    });

    const { onRequest, messages, setMessages } = useXChat({
        agent,
    });

    useEffect(() => {
        debounce(() => {
            if (messages[messages.length - 2]?.message) {
                setConversationsItems((items) => {
                    const data = items.find((item) => item.key == activeKey)
                    if (data) {
                        data.label = messages[messages.length - 2]?.message.slice(0, 10) + '...'
                        data.data = _.cloneDeep(messages)
                    }
                    return items
                })
            }
        });

    }, [messages])

    const senderPromptsItems: GetProp<typeof Prompts, 'items'> = [
        {
            key: '1',
            description: '你是谁？',
            icon: <FireOutlined style={{ color: '#FF4D4F' }} />,
        },
        {
            key: '2',
            description: '你能为我做什么？',
            icon: <ReadOutlined style={{ color: '#1890FF' }} />,
        },
    ];

    const onPromptsItemClick: GetProp<typeof Prompts, 'onItemClick'> = (info) => {
        onRequest(info.data.description as string);
    };

    const placeholderNode = (
        <Space direction="vertical" size={16} >
            <Welcome
                variant="borderless"
                icon={<div className='w-[60px] h-[60px]'>
                    <img src="img/ai.webp" />
                </div>
                }
                title={`你好，我是${title}`}
                description="智能AI助手：赋能未来的解决方案"
                extra={
                    sidebar && <Space>
                        <Button icon={<ShareAltOutlined />} />
                        <Button icon={<EllipsisOutlined />} />
                    </Space>
                }
            />
            {/* <Prompts
                title="你想要?"
                items={placeholderPromptsItems}
                styles={{
                    list: {
                        width: '100%',
                    },
                    item: {
                        flex: 1,
                    },
                }}
                onItemClick={onPromptsItemClick}
            /> */}
        </Space>
    );

    const onConversationClick: GetProp<typeof Conversations, 'onActiveChange'> = (key) => {
        const data = conversationsItems.find((item) => item.key === key)?.data
        setMessages(data);
        setActiveKey(key);
    };

    // 重新循环配置ID
    useEffect(() => {
        setConversationsItems((conversationsItems) => {
            conversationsItems.forEach((items) =>
                items.data.forEach((item) => item.id = uuidv4())
            )
            return [...conversationsItems]
        })

    }, [])

    const onAddConversation = () => {
        const key = uuidv4();
        const time = fromTime()
        setConversationsItems([
            {
                key: key,
                label: '新聊天',
                group: time + "",
                data: [],
                timestamp: time,
            },
            ...conversationsItems
        ]);
        setActiveKey(key);
        setMessages([]);
    };

    const groupable: GetProp<typeof Conversations, 'groupable'> = {
        sort(a: any, b: any) {
            return a - b > 0 ? -1 : 1;
        },
        title: (group, { components: { GroupTitle } }) =>
            group ? (
                <GroupTitle>
                    <Space>
                        <span>{formatTimestamp(group)}</span>
                    </Space>
                </GroupTitle>
            ) : (
                <GroupTitle />
            ),
    };

    const { variable } = useVariable()

    return (
        <div className='w-full h-full flex bg-white'>
            {sidebar && <div className='max-lg:hidden w-[260px] bg-[#FAFAFA]' style={{ borderRight: '1px solid #E9E8EB' }}>
                <div className="flex m-[14px]">
                    <img
                        src="img/logo-v1.webp"
                        draggable={false}
                        alt="logo"
                        style={{ height: 30 }}
                    />
                    <span className='ml-2 font-bold mt-1'>AI智能体平台</span>
                </div>
                <div className='pl-[12px] pr-[12px]'>
                    <Button
                        onClick={onAddConversation}
                        type="link"
                        className='bg-[#EDF2FB] w-full'
                        style={{ border: '1px solid #C7D6EC' }}
                        icon={<PlusOutlined />}
                    >
                        新聊天
                    </Button>
                </div>
                <Conversations
                    items={conversationsItems}
                    groupable={groupable}
                    activeKey={activeKey}
                    style={{ height: 'calc(100vh - 90px)' }}
                    menu={menuConfig}
                    onActiveChange={onConversationClick}
                />
            </div>}
            <div className='w-full flex flex-1 justify-center max-lg:p-[10px] lg:p-[60px]' style={{ padding: sidebar ? 50 : 0 }}>
                <div className='h-full max-w-[900px] w-full flex flex-col'>
                    {messages.length == 0 && placeholderNode}
                    <Bubble.List
                        autoScroll={true}
                        roles={roles}
                        style={{ background: 'white' }}
                        ref={listRef}
                        items={messages.map(({ id, message: msg, status }) => {
                            return {
                                key: id,
                                styles: status === 'local' ? {
                                    content: {
                                        borderRadius: "10px 0px 10px 10px"
                                    }
                                } : {
                                    content: {
                                        borderRadius: "0px 10px 10px 10px"
                                    }
                                },
                                role: status === 'local' ? 'local' : 'ai',
                                content: <MarkdownRender markdown={msg} />,
                                loading: msg == "...",
                                footer: status === 'local' ? undefined : <Flex>
                                    <Button
                                        size="small"
                                        type="text"
                                        icon={<SyncOutlined />}
                                        onClick={() => {
                                            const index = messages.findIndex((item) => item.id == id)
                                            const data = messages[index - 1]
                                            onRequest(data.message);
                                            setMessages((message) => {
                                                return message.slice(0, index);
                                            })
                                        }}
                                        style={{ marginInlineEnd: 'auto' }}
                                    />
                                    <Button size="small" type="text" icon={<LikeOutlined />}
                                        onClick={() => {
                                            message.success('感谢您的评价');
                                        }} />
                                    <Button size="small" type="text" icon={<DislikeOutlined />}
                                        onClick={() => {
                                            message.success('我会再接再厉');
                                        }} />
                                    <Button size="small" type="text" icon={<CopyOutlined />}
                                        onClick={() => {
                                            try {
                                                // 优先使用现代 Clipboard API
                                                if (navigator.clipboard && window.isSecureContext) {
                                                    navigator.clipboard.writeText(msg)
                                                        .then(() => message.success('复制成功'))
                                                        .catch(err => {
                                                            message.error('复制失败');
                                                            console.error('复制失败:', err);
                                                        });
                                                } else {
                                                    // 降级方案: 使用传统 document.execCommand
                                                    const textArea = document.createElement('textarea');
                                                    textArea.value = msg;
                                                    document.body.appendChild(textArea);
                                                    textArea.select();
                                                    const success = document.execCommand('copy');
                                                    document.body.removeChild(textArea);

                                                    if (success) {
                                                        message.success('复制成功');
                                                    } else {
                                                        message.error('复制失败');
                                                    }
                                                }
                                            } catch (err) {
                                                message.error('复制失败');
                                                console.error('复制失败:', err);
                                            }
                                        }} />
                                </Flex>,
                            }
                        })}
                        className='mb-4 scrollbar-hide'
                    />
                    <div className='mt-auto relative'>
                        {sidebar && <Prompts styles={{
                            list: {
                            },
                            item: {
                                paddingBlock: 6,
                                paddingInline: 10,
                            },
                        }} items={senderPromptsItems} className='mb-2' onItemClick={onPromptsItemClick} />}

                        <Suggestion
                            items={suggestions}
                            onSelect={(itemVal) => {
                                setContent(itemVal)
                            }}
                        >
                            {({ onTrigger, onKeyDown }) => {
                                return <Sender
                                    placeholder="输入 / 获取建议"
                                    // allowSpeech={true}
                                    loading={agent.isRequesting()}
                                    value={content}
                                    prefix={
                                        <>
                                            <Button
                                                type="text"
                                                icon={<DeleteOutlined className='text-[#1877FF]' />}
                                                onClick={() => {
                                                    setMessages([])
                                                }}
                                            />
                                            <Button
                                                type="text"
                                                icon={<PlusCircleOutlined className='text-[#1877FF]' />}
                                                onClick={() => {
                                                    setIsParams(true)
                                                }}
                                            />
                                        </>
                                    }
                                    onChange={(nextVal) => {
                                        if (nextVal === '/') {
                                            onTrigger();
                                        } else if (!nextVal) {
                                            onTrigger(false);
                                        }
                                        setContent(nextVal)
                                    }}
                                    onSubmit={(nextContent) => {
                                        onRequest(nextContent);
                                        setContent('');
                                    }}
                                    onCancel={() => {
                                        stopRef.current = true
                                    }}
                                />
                            }}
                        </Suggestion>
                    </div>

                    <Modal title="自定义参数" open={isParams} onCancel={() => setIsParams(false)} footer={null}>
                        <Form
                            {...layout}
                            form={form}
                            onFinish={() => { }}
                            style={{ maxWidth: 600 }}
                        >
                            {variable.filter(v => v.value != "sys.query" && v.value != "sys.result" && v.value.startsWith("sys."))
                                .map(v =>
                                    <Form.Item name={v.value} label={v.label}>
                                        <Input autoComplete="off" />
                                    </Form.Item>)}
                        </Form>
                    </Modal>
                </div>
            </div>
        </div>
    );
};


export default ChatWhite;